package java8.myStream;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 功能描述: 手记完成后的 更进一步的映射
 * 2024/08/26
 *
 * @author ZhangYi
 */
public class CollectingAndThenTest {
	/***
	 * 将所有人的名字收集到一个列表中，并将其转换为不可变列表：
		 * 使用 Collectors.mapping(Person::getName, Collectors.toList()) 映射每个人的名字，并将其收集到一个列表中。
		 * 使用 Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList) 将列表转换为不可变列表。
	 * 将所有人的年龄收集到一个列表中，并计算它们的总和：
		 * 使用 Collectors.mapping(Person::getAge, Collectors.toList()) 映射每个人的年龄，并将其收集到一个列表中。
		 * 使用 Collectors.collectingAndThen(Collectors.toList(), list -> list.stream().reduce(0, Integer::sum)) 计算年龄的总和。
	 * 将所有人的年龄收集到一个列表中，并计算它们的平均值：
		 * 使用 Collectors.mapping(Person::getAge, Collectors.toList()) 映射每个人的年龄，并将其收集到一个列表中。
		 * 使用 Collectors.collectingAndThen(Collectors.toList(), list -> list.stream().mapToInt(Integer::intValue).average().orElse(0.0)) 计算年龄的平均值。
	 * 将所有人的年龄收集到一个列表中，并统计每个年龄的人数：
		 * 使用 Collectors.mapping(Person::getAge, Collectors.toList()) 映射每个人的年龄，并将其收集到一个列表中。
		 * 使用 Collectors.collectingAndThen(Collectors.toList(), list -> list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))) 统计每个年龄的人数。
	 * 将所有人的年龄收集到一个列表中，并按年龄分组：
		 * 使用 Collectors.mapping(Person::getAge, Collectors.toList()) 映射每个人的年龄，并将其收集到一个列表中。
		 * 使用 Collectors.collectingAndThen(Collectors.toList(), list -> list.stream().collect(Collectors.groupingBy(age -> age, Collectors.toList()))) 按年龄分组。
	 * 这些示例展示了 collectingAndThen 如何与其他收集器结合使用，以实现更复杂的流处理任务。
	 * @param args
	 */
	public static void main(String[] args) {
		List<Person> people = Arrays.asList(
				new Person("Alice", 20),
				new Person("Bob", 17),
				new Person("Charlie", 22),
				new Person("Diana", 19),
				new Person("Eve", 25),
				new Person("Frank", 16)
		);

		// 1. 将所有人的名字收集到一个列表中，并将其转换为不可变列表
		List<String> names = people.stream()
				.collect(Collectors.mapping(Person::getName,
						Collectors.collectingAndThen(Collectors.toList(),
								Collections::unmodifiableList)));
		System.out.println("Names: " + names);

		// 2. 将所有人的年龄收集到一个列表中，并计算它们的总和
		int totalAge = people.stream()
				.collect(Collectors.mapping(Person::getAge,
						Collectors.collectingAndThen(Collectors.toList(),
								list -> list.stream().reduce(0, Integer::sum))));
		System.out.println("Total Age: " + totalAge);

		// 3. 将所有人的年龄收集到一个列表中，并计算它们的平均值
		double averageAge = people.stream()
				.collect(Collectors.mapping(Person::getAge,
						Collectors.collectingAndThen(Collectors.toList(),
								list -> list.stream().mapToInt(Integer::intValue).average().orElse(0.0))));
		System.out.println("Average Age: " + averageAge);

		// 4. 将所有人的年龄收集到一个列表中，并统计每个年龄的人数
		Map<Integer, Long> ageCount = people.stream()
				.collect(Collectors.mapping(Person::getAge,
						Collectors.collectingAndThen(Collectors.toList(),
								list -> list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())))));
		System.out.println("Age Count: " + ageCount);

		// 5. 将所有人的年龄收集到一个列表中，并按年龄分组
//		Map<Integer, List<Person>> groupedByAge = people.stream()
//				.collect(Collectors.mapping(Person::getAge,
//						Collectors.collectingAndThen(Collectors.toList(),
//								list4 -> list4.stream().collect(Collectors.groupingBy(age -> age, Collectors.toList())))));
//		System.out.println("Grouped by Age: " + groupedByAge);
	}
}
